using System;
using System.Collections.Generic;
using System.IO;
using NLog;
using WCell.Core.Addons;
using WCell.Core.Initialization;
using WCell.RealmServer.Commands;
using WCell.Util.Variables;

namespace WCell.RealmServer.Addons
{
	/// <summary>
	/// Static helper and container class of all kinds of Addons
	/// </summary>
	public static class RealmAddonMgr
	{
		static Logger log = LogManager.GetCurrentClassLogger();

		public static string AddonDir = "../Lib";

		/// <summary>
		/// A list of all external libraries and addons to be loaded.
		/// A description is either a simple dll filename or the filename, followed by a comma, followed by 
		/// the fully specified typename of the Plugin-Class to be activated and initialized.
		/// </summary>
		public static string AddonDescriptions = "WCell.DefaultAddon.dll, WCell.Addons.DefaultAddon; WCell.Collision.dll, WCell.Collision.Addon.CollisionAddon";

		private static bool inited;

		[Initialization(InitializationPass.First, "Initialize Addons")]
		public static void Initialize(InitMgr mgr)
		{
			if (inited)
			{
				return;
			}
			inited = true;

			// descriptors.LoadAll(true);
			WCellAddonDescriptor.ParseDefault(AddonDir, AddonDescriptions);
			//WCellAddonMgr.RegisterResolveHandler();

			if (WCellAddonMgr.Descriptors.Count > 0)
			{
				log.Info("Found {0} Addon(s):", WCellAddonMgr.Descriptors.Count);
				foreach (var desc in WCellAddonMgr.Descriptors)
				{
				    Load(mgr, desc);
				}
			}
			else
			{
				log.Info("No addons found.");
			}
		}

	    public static void Load(WCellAddonDescriptor desc)
	    {
	        var mgr = new InitMgr();
	        Load(mgr, desc);
            mgr.PerformInitialization();
	    }

	    public static void Load(InitMgr mgr, WCellAddonDescriptor desc)
	    {
            if (!desc.Exists)
            {
                throw new FileNotFoundException("Could not find Addon file: " + desc.FilePath);
            }

            try
            {
                if (desc.TypeName != null)
                {
                    log.Info("Loading Addon from {0}...", desc.FilePath);
                }
                else
                {
                    log.Info("Loading Library from {0}...", desc.FilePath);
                }

                var context = new WCellAddonContext(desc, true);

                // add all initialization steps of the Assembly
                mgr.AddStepsOfAsm(context.Assembly);
                InitAddon(context);
            }
            catch (Exception e)
            {
                throw new Exception("Failed to load Addon - " + desc, e);
            }
	    }

	    private static void InitAddon(WCellAddonContext context)
		{
			log.Info("Loaded: " + (context.Addon != null
						? context.Addon.GetDefaultDescription()
						: (context.Assembly.GetName().Name)));

			var addon = context.Addon;

			// register all Commands of the Assembly
			RealmCommandHandler.Instance.AddCmdsOfAsm(context.Assembly);

			if (addon != null)
			{
				// init config
				if (addon is WCellAddonBase)
				{
					((WCellAddonBase)addon).InitConfig(context);
				}
			}
		}
	}
}
